﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.RobotJog.CApRJRobotJogGhostGunDisplayer
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using EngineeringInternalExtension;
using System.Collections.Generic;
using Tecnomatix.Engineering;
using Tecnomatix.Engineering.Olp;


namespace DnProcessSimulateCommands.RobotJog;

internal class CApRJRobotJogGhostGunDisplayer
{
  private ITxRobot _robot;
  private ITxObject _gun;
  private ITxRoboticLocationOperation _location;
  private TxGhostGunEx _ghostGunCreator = new TxGhostGunEx();
  private ITxRoboticControllerServices _controllerServices;

  public CApRJRobotJogGhostGunDisplayer(ITxRobot robot)
  {
    this._robot = robot;
    if (this._robot == null)
      return;
    this._controllerServices = this.GetControllerServices();
  }

  public bool IsDisplayed { get; private set; }

  private ITxObject Gun
  {
    get => this._gun;
    set
    {
      this.UnregisterFromGunEvents(this._gun);
      this.HideGun();
      this._gun = value;
      if (this._gun == null)
        return;
      this.RegisterForGunEvents(this._gun);
      this.ShowGunOnLocation();
    }
  }

  private ITxRoboticLocationOperation Location
  {
    get => this._location;
    set
    {
      this.UnregisterFromLocationEvents(this._location);
      if (this._robot != CApRJRobotJogUtilities.GetRoboticLocationOperationAssignedRobot((ITxObject) value))
      {
        this._location = (ITxRoboticLocationOperation) null;
        this.Gun = (ITxObject) null;
      }
      else
      {
        this._location = value;
        this.RegisterForLocationEvents(this._location);
        this.Gun = this.GetActiveGun();
      }
    }
  }

  public void Show(ITxRoboticLocationOperation location) => this.Location = location;

  public void Hide()
  {
    if (!this.IsDisplayed)
      return;
    this.Gun = (ITxObject) null;
    this.Location = (ITxRoboticLocationOperation) null;
  }

  private void ShowGunOnLocation()
  {
    if (this.Location == null || this.IsDisplayed)
      return;
    Dictionary<TxJoint, double> savedValues = this.SetExternalValuesOnLocation();
    this._ghostGunCreator.CreateGhostGun(this.Gun, false);
    this.JumpGunToLocation();
    if (savedValues.Count > 0)
    {
      this.RestoreChangedJointValues(savedValues);
      TxApplication.ActiveUndoManager.ClearAllTransactions();
    }
    this.IsDisplayed = true;
  }

  private void JumpGunToLocation()
  {
    TxTransformation relativeLocation = this._controllerServices.GetActiveMountedTcpRelativeLocation((ITxLocationOperation) this.Location);
    if (TxTransformation.op_Inequality(relativeLocation, (TxTransformation) null))
    {
      TxTransformation gunTcpfForJump = TxGhostGunEx.GetGunTCPFForJump(this.Gun);
      this._ghostGunCreator.JumpGhostGunToLocation(TxTransformation.op_Multiply((this.Location as ITxLocatableObject).AbsoluteLocation, TxTransformation.op_Multiply(TxTransformation.op_Multiply(this._robot.Toolframe.AbsoluteLocation, relativeLocation).Inverse, gunTcpfForJump)));
    }
    else
      this._ghostGunCreator.JumpGhostGunToLocation(this.Location);
  }

  private void HideGun()
  {
    if (!this.IsDisplayed)
      return;
    this._ghostGunCreator.DestroyGhostGun();
    this.IsDisplayed = false;
  }

  private void RegisterForGunEvents(ITxObject gun)
  {
    if (gun == null)
      return;
    gun.Deleted += new TxObject_DeletedEventHandler(this.GunDeleted);
    (gun as ITxDisplayableObject).VisibilitySet += new TxDisplayableObject_VisibilitySetEventHandler(this.GunVisibilitySet);
  }

  private void UnregisterFromGunEvents(ITxObject gun)
  {
    if (gun == null)
      return;
    gun.Deleted -= new TxObject_DeletedEventHandler(this.GunDeleted);
    (gun as ITxDisplayableObject).VisibilitySet -= new TxDisplayableObject_VisibilitySetEventHandler(this.GunVisibilitySet);
  }

  private void GunVisibilitySet(object sender, TxDisplayableObject_VisibilitySetEventArgs args)
  {
    ITxDisplayableObject gun = this.Gun as ITxDisplayableObject;
    if (gun.Visibility == null || gun.Visibility == 1)
    {
      this._controllerServices.Init(this._robot as TxRobot);
      this.ShowGunOnLocation();
    }
    else
      this.HideGun();
  }

  private void RegisterForLocationEvents(ITxRoboticLocationOperation location)
  {
    if (location == null)
      return;
    (location as ITxLocatableObject).AbsoluteLocationChanged += new TxLocatableObject_AbsoluteLocationChangedEventHandler(this.LocationAbsoluteLocationChanged);
    ((ITxObject) location).Deleted += new TxObject_DeletedEventHandler(this.LocationDeleted);
  }

  private void UnregisterFromLocationEvents(ITxRoboticLocationOperation location)
  {
    if (location == null)
      return;
    (location as ITxLocatableObject).AbsoluteLocationChanged -= new TxLocatableObject_AbsoluteLocationChangedEventHandler(this.LocationAbsoluteLocationChanged);
    ((ITxObject) location).Deleted -= new TxObject_DeletedEventHandler(this.LocationDeleted);
  }

  private void GunDeleted(object sender, TxObject_DeletedEventArgs args) => this.Hide();

  private void LocationDeleted(object sender, TxObject_DeletedEventArgs args) => this.Hide();

  private void LocationAbsoluteLocationChanged(
    object sender,
    TxLocatableObject_AbsoluteLocationChangedEventArgs args)
  {
    this._ghostGunCreator.JumpGhostGunToLocation(this.Location);
  }

  private ITxRoboticControllerServices GetControllerServices()
  {
    TxOlpControllerUtilities controllerUtilities = new TxOlpControllerUtilities();
    if (!(controllerUtilities.GetInterfaceImplementationFromController(this._robot.Controller.Name, typeof (ITxRoboticControllerServices), typeof (TxControllerAttribute), "ControllerName") is ITxRoboticControllerServices implementationFromController))
      implementationFromController = controllerUtilities.GetInterfaceImplementationFromController("default", typeof (ITxRoboticControllerServices), typeof (TxControllerAttribute), "ControllerName") as ITxRoboticControllerServices;
    return implementationFromController;
  }

  private ITxObject GetActiveGun()
  {
    if (this._controllerServices == null)
      return (ITxObject) null;
    ITxObject activeGun = (ITxObject) null;
    try
    {
      this._controllerServices.Init(this._robot as TxRobot);
      activeGun = (ITxObject) this._controllerServices.GetActiveGun((ITxLocationOperation) this.Location) ?? (ITxObject) this._controllerServices.GetActiveGripper((ITxLocationOperation) this.Location);
      if (activeGun != null)
      {
        if (!activeGun.IsValid())
          activeGun = (ITxObject) null;
      }
    }
    catch
    {
    }
    return activeGun;
  }

  private Dictionary<TxJoint, double> SetExternalValuesOnLocation()
  {
    Dictionary<TxJoint, double> dictionary = new Dictionary<TxJoint, double>();
    if (!(this.Gun is ITxDevice gun) || this.Location == null || this.Location.RobotExternalAxesData == null)
      return dictionary;
    TxObjectList drivingJoints = gun.DrivingJoints;
    foreach (TxRobotExternalAxisData externalAxisData in this.Location.RobotExternalAxesData)
    {
      if (externalAxisData.Device == gun)
      {
        dictionary.Add(externalAxisData.Joint, externalAxisData.Joint.CurrentValue);
        externalAxisData.Joint.CurrentValue = externalAxisData.JointValue;
      }
    }
    return dictionary;
  }

  private void RestoreChangedJointValues(Dictionary<TxJoint, double> savedValues)
  {
    if (savedValues == null)
      return;
    foreach (KeyValuePair<TxJoint, double> savedValue in savedValues)
      savedValue.Key.CurrentValue = savedValue.Value;
  }
}
